        #include "queue.h"
        #include "fata.h"
        #include <stdlib.h>

        #define MinQueueSize ( 5 )

        struct QueueRecord
        {
            int Capacity;
            int Front;
            int Rear;
            int Size;
            ElementType *Array;
        };

/* START: fig3_58.txt */
        int
        IsEmpty( Queue Q )
        {
            return Q->Size == 0;
        }
/* END */

        int
        IsFull( Queue Q )
        {
            return Q->Size == Q->Capacity;
        }

        Queue
        CreateQueue( int MaxElements )
        {
            Queue Q;
            if (MaxElements < MinQueueSize)
                Error( "Queue size is too small" );

            Q = malloc( sizeof( struct QueueRecord ) );
            if ( Q == NULL )
                FataError( "Out of space!" );

            Q->Array = malloc( sizeof( ElementType ) * MaxElements );
            if ( Q->Array == NULL )
                FataError( "Out of space!" );
            Q->Capacity = MaxElements;
            MakeEmpty( Q );

            return Q;
        }

/* START: fig3_59.txt */
        void
        MakeEmpty( Queue Q )
        {
            Q->Size = 0;
            Q->Front = 1;
            Q->Rear = 0;
        }
/* END */

        void
        DisposeQueue( Queue Q )
        {
            if ( Q != NULL )
            {
                free( Q->Array );
                free( Q );
            }
        }

/* START: fig3_60.txt */ 
        static int
        Succ( int Value, Queue Q )
        {
            if ( ++Value == Q->Capacity )
                Value = 0;
            return Value;
        }

        void
        Enqueue( ElementType X, Queue Q )
        {
            if ( IsFull( Q ) )
                Error( "Full queue" );
            else
            {
                Q->Size++;
                Q->Rear = Succ(Q->Rear, Q);
                Q->Array[ Q->Rear ] = X;
            }
        }
/* END */

        ElementType
        Front( Queue Q )
        {
            if ( !IsEmpty( Q ) )
                return Q->Array[ Q->Front ];
            Error( "Empty queue" );
            return 0;
        }

        void
        Dequeue( Queue Q )
        {
            if ( IsEmpty( Q ) )
                Error( "Empty queue" );
            else
            {
                Q->Size--;
                Q->Front = Succ( Q->Front, Q );
            }
        }

        ElementType
        FrontAndDequeue( Queue Q )
        {
            ElementType X = 0;
            if ( IsEmpty( Q ) )
                Error( "Empty Queue" );
            else
            {
                Q->Size--;
                X = Q->Array[ Q->Front ];
                Q->Front = Succ( Q->Front, Q );
            }
            return X;
        }

